from . models import User
from rest_framework import serializers
import re
from .utils import get_user_by_account
from django.contrib.auth.hashers import make_password
from rest_framework_jwt.settings import api_settings

class UserModelSerializer(serializers.ModelSerializer):
    '''注册用户的序列化器'''
    sms_code = serializers.CharField(min_length=4, max_length=6,
                                     required=True, help_text='短信验证码',
                                     write_only=True,) #--->无需返回前端
    token = serializers.CharField(max_length=1024, read_only=True,
                                  help_text="token认证字符串")


    class Meta:
        model = User
        fields = ['id', 'mobile', 'password', 'sms_code', 'username', 'token']

        extra_kwargs = {
            'id': {
                'read_only': True, #需要后端返回前端 不需要前端向后端设置
            },
            'mobile': {
                'write_only': True, # 不需要返回前端
            },
            'password': {
                'write_only': True,
            },
            'username': {
                'read_only': True,
            },
        }

    def validate(self, attrs):

        '''
        全局钩子
        :param attrs:提交经过基础验证之后的所有的字段 字典的形式
        :return
        '''

        mobile = attrs.get('mobile')
        sms_code = attrs.get('sms_code')

        # 验证手机号格式
        if not re.match(r"1[3-9]\d{9}$", mobile):
            raise serializers.ValidationError('对不起，手机号格式有误')

        # 验证手机号是否注册过
        user = get_user_by_account(mobile)
        print('-------->', user)
        if user:
            raise serializers.ValidationError("该手机号已经注册过！")

        # todo 短信验证码验证功能
        from django_redis import get_redis_connection
        redis_conn = get_redis_connection ('sms_code')
        redis_sms_code = redis_conn.get(f'sms_{mobile}').decode()
        # print(redis_sms_code, type(redis_sms_code)) #bytes
        # print(sms_code, type(sms_code)) # str
        if sms_code != redis_sms_code:
            raise serializers.ValidationError("验证码输入有误")
        return attrs
    def create(self, validated_data):
        """
        重写给数据库插入数据的方法
        :param validated_data:
        :return:
        """
        validated_data.pop('sms_code')
        raw_password = validated_data.get('password')
        hash_password = make_password(raw_password)
        mobile = validated_data.get('mobile')
        user = User.objects.create(
            mobile=mobile,
            password=hash_password,
            username=mobile
        )

        # 前端接收token  利用JWT提供的功能生成token
        # from rest_framework_jwt.settings import api_settings
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        user.token = token
        return user